/*
 * ItemActions.java
 */

package nxtgeninventorysystem.Controller;

import java.util.ArrayList;
import nxtgeninventorysystem.Data.Item;
import nxtgeninventorysystem.Data.ItemSearchOptions;
import nxtgeninventorysystem.Data.Person;
import nxtgeninventorysystem.Data.Transaction;
import nxtgeninventorysystem.Data.TransactionSearchOptions;
import nxtgeninventorysystem.Model.Database;
import nxtgeninventorysystem.View.Dialog.CreateItemType;
import nxtgeninventorysystem.View.Dialog.EditItemType;
import nxtgeninventorysystem.View.Dialog.ModifyItem;
import nxtgeninventorysystem.View.Gui;
import nxtgeninventorysystem.View.Gui.Dialog;

/**
 * The ItemActions class is a Controller class inside the Model-View-Controller
 * design pattern. This class typically deals with the Item entity in the
 * database, allowing flow of data between the View (Gui) and the Model
 * (Database).
 * @author Seraph Softworks
 */
public final class ItemActions extends Actions {

    //idea: use one thread for all functions

    public ItemActions() {

    }

    public void gotoCreateItem() {
        Thread t = new Thread() {
            public void run() {
                while(busy) {

                }
                busy = true;

                ModifyItem form = (ModifyItem) Gui.getDialog(Dialog.CreateItem);
                form.setTargetItem(null);
                form.resetFields();

                busy = false;

                Gui.showDialog(Dialog.CreateItem);
            }
        };
        t.start();
    }

    public void doCreateItem() {
        Thread t = new Thread() {
            public void run() {
                ModifyItem form = (ModifyItem) Gui.getDialog(Dialog.CreateItem);
                form.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Creating New Item...");

                Item item = form.getFormItem();
                int id = Database.item.createItem(item);

                Gui.setReadItemPage(Database.item.readItem(id), Database.item.getItemTransactions(item.getId(), new TransactionSearchOptions(), true));

                form.setEnabled(true);
                form.dispose();
                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                Gui.goToPage(Gui.Page.ReadItem);

                busy = false;
            }
        };
        t.start();
    }

    public void gotoBrowseItem() {
        Thread t = new Thread() {
            public void run() {
                while(busy) {

                }
                busy = true;

                Gui.goToPage(Gui.Page.BrowseItem);

                busy = false;

                Actions.item.doSearchItem();
            }
        };
        t.start();
    }

    public void doSearchItem() {
        Thread t = new Thread() {
            public void run() {
                Gui.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Retreiving Search Results...");

                Gui.setBrowseItemPage(new ArrayList <Item> ());

                Item values = Gui.getItemSearchValues(Gui.getCurrentPage());
                ItemSearchOptions options = Gui.getItemSearchOptions(Gui.getCurrentPage());
                ItemSearchOptions order = Gui.getItemOrderAtPage(Gui.getCurrentPage());
                ArrayList <Item> itemlist = null;
                switch(Gui.getCurrentPage()) {
                    case BrowseItem:
                        itemlist = Database.item.searchItem(values, options, order, true);
                        Gui.setBrowseItemPage(itemlist);
                        break;
                }

                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                Gui.setEnabled(true);

                busy = false;
            }
        };
        t.start();
    }

    public void gotoReadItem() {
        Thread t = new Thread() {
            public void run() {
                Gui.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Retreiving Item Information...");

                Item item = null;

                switch(Gui.getCurrentPage()) {
                    case ReadItem:
                        item = Gui.getReadItemTarget();
                        break;
                    default:
                        ArrayList <Item> items = Gui.getItemsSelectedAtPage(Gui.getCurrentPage());
                        if(items == null)
                            return;
                        item = items.get(0);
                        break;
                }

                if(item == null)
                    return;

                Gui.setReadItemPage(Database.item.readItem(item.getId()), Database.item.getItemTransactions(item.getId(), Gui.getTransactionOrderAtPage(Gui.Page.ReadItem), true));

                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                Gui.setEnabled(true);

                Gui.goToPage(Gui.Page.ReadItem);

                busy = false;
            }
        };
        t.start();
    }

    public void gotoUpdateItem() {
        Thread t = new Thread() {
            public void run() {
                while(busy) {

                }
                busy = true;

                Item item = Gui.getReadItemTarget();

                if(item == null)
                    return;

                ModifyItem form = (ModifyItem) Gui.getDialog(Dialog.EditItem);
                form.setTargetItem(item);
                form.resetFields();

                busy = false;

                Gui.showDialog(Dialog.EditItem);
            }
        };
        t.start();
    }

    public void doUpdateItem() {
        Thread t = new Thread() {
            public void run() {
                ModifyItem form = (ModifyItem) Gui.getDialog(Dialog.EditItem);
                form.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Updating Item Information...");

                Item formitem = form.getFormItem();
                Item primeitem = form.getTargetItem();
                primeitem.setName(formitem.getName());
                primeitem.setDescription(formitem.getDescription());
                primeitem.setType(formitem.getType());

                Database.item.updateItem(primeitem);

                Gui.setReadItemPage(Database.item.readItem(primeitem.getId()), Database.item.getItemTransactions(primeitem.getId(),Gui.getTransactionOrderAtPage(Gui.Page.ReadItem),true));

                form.setEnabled(true);
                form.dispose();
                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                Gui.setEnabled(true);

                Gui.goToPage(Gui.Page.ReadItem);

                busy = false;
            }
        };
        t.start();
    }

    public void doDeleteItem() {
        Thread t = new Thread() {
            public void run() {
                Gui.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Deleting Selected Item(s)...");

                ArrayList <Item> items = Gui.getItemsSelectedAtPage(Gui.Page.BrowseItem);

                if(items != null) {
                    for(Item item : items) {
                        Database.item.deleteItem(item.getId());
                    }
                }

                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                Gui.setEnabled(true);

                busy = false;

                Actions.item.gotoBrowseItem();
            }
        };
        t.start();
    }

    public void gotoBorrowItems() {
        Thread t = new Thread() {
            public void run() {
                Gui.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Initializing Cart...");

                Gui.resetBorrowItemPurpose();
                Gui.goToPage(Gui.Page.BorrowItem);

                ArrayList <Item> items = Gui.getItemsSelectedAtPage(Gui.Page.BrowseItem);

                boolean ok = false;
                while(!ok) {
                    ok = true;
                    for(int i = 0 ; i < items.size() ; i++) {
                        if(items.get(i).getPerson() != null) {
                            items.remove(i);
                            ok = false;
                            break;
                        }
                    }
                }

                Gui.setBorrowItems(new ArrayList <Person> (), items);

                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                Gui.setEnabled(true);

                busy = false;

                Actions.person.doSearchPerson();
            }
        };
        t.start();
    }

    public void doBorrowItems() {
        Thread t = new Thread() {
            public void run() {
                if(Gui.getPersonsSelectedAtPage(Gui.Page.BorrowItem) == null) {
                    Gui.setStatusBarMessage("Please Specify The Borrower...");
                    return;
                }
                if(Gui.getPersonsSelectedAtPage(Gui.Page.BorrowItem).isEmpty()) {
                    Gui.setStatusBarMessage("Please Specify The Borrower...");
                    return;
                }
                if(Gui.getDisplayedItemsAtPage(Gui.Page.BorrowItem).isEmpty()) {
                    Gui.setStatusBarMessage("Item Cart Is Empty...");
                    return;
                }

                Gui.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Recording Borrow Transaction...");

                Person person = Gui.getPersonsSelectedAtPage(Gui.Page.BorrowItem).get(0);
                ArrayList <Item> items = Gui.getDisplayedItemsAtPage(Gui.Page.BorrowItem);

                Transaction transaction = new Transaction();
                transaction.setPerson(person);
                transaction.setType(Transaction.BORROW);
                transaction.setPurpose(Gui.getBorrowItemPurpose());
                transaction.setItems(items);
                int id = Database.transaction.createTransaction(transaction);
                for(Item item : items) {
                    item.setPerson(person);
                    Database.item.updateItem(item);
                }

                Gui.setReadTransaction(Database.transaction.readTransaction(id), Database.transaction.getTransactionItems(id,Gui.getItemOrderAtPage(Gui.Page.ReadTransaction),true));

                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                Gui.setEnabled(true);

                Gui.goToPage(Gui.Page.ReadTransaction);

                busy = false;
            }
        };
        t.start();
    }

    public void doReturnItem() {
        Thread t = new Thread() {
            public void run() {
                Gui.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Returning Items...");

                ArrayList <Item> items = Gui.getItemsSelectedAtPage(Gui.Page.ReadPerson);
                Person person = Gui.getReadPersonTarget();

                Transaction transaction = new Transaction();
                transaction.setPerson(person);
                transaction.setType(Transaction.RETURN);
                transaction.setPurpose("Returning of item.");
                transaction.setItems(items);
                int id = Database.transaction.createTransaction(transaction);
                for(Item item : items) {
                    item.setPerson(null);
                    Database.item.updateItem(item);
                }

                Gui.setReadTransaction(Database.transaction.readTransaction(id), Database.transaction.getTransactionItems(id,Gui.getItemOrderAtPage(Gui.Page.ReadTransaction),true));

                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                Gui.setEnabled(true);

                Gui.goToPage(Gui.Page.ReadTransaction);

                busy = false;
            }
        };
        t.start();
    }

    public void gotoCreateItemType() {
        Thread t = new Thread() {
            public void run() {
                while(busy) {

                }
                busy = true;

                CreateItemType form = (CreateItemType) Gui.getDialog(Dialog.CreateItemType);
                form.resetFields();

                busy = false;

                Gui.showDialog(Dialog.CreateItemType);
            }
        };
        t.start();
    }

    public void doCreateItemType() {
        Thread t = new Thread() {
            public void run() {
                CreateItemType form = (CreateItemType) Gui.getDialog(Dialog.CreateItemType);
                ModifyItem crt = (ModifyItem) Gui.getDialog(Dialog.CreateItem);
                ModifyItem edi = (ModifyItem) Gui.getDialog(Dialog.EditItem);
                form.setEnabled(false);
                crt.setEnabled(false);
                edi.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Creating New Item Type...");

                String type = form.getItemTypeNameValue();
                boolean good = Database.item.createItemType(type);

                Gui.refreshComboBoxes(Database.item.readItemTypes(), Database.person.readTeams());

                form.setEnabled(true);
                form.dispose();

                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                busy = false;

                crt.setEnabled(true);
                edi.setEnabled(true);

                Actions.item.gotoBrowseItem();
            }
        };
        t.start();
    }

    public void gotoUpdateItemType() {
        Thread t = new Thread() {
            public void run() {
                while(busy) {

                }
                busy = true;

                EditItemType form = (EditItemType) Gui.getDialog(Dialog.EditItemType);
                form.resetFields();

                busy = false;

                Gui.showDialog(Dialog.EditItemType);
            }
        };
        t.start();
    }

    public void doUpdateItemType() {
        Thread t = new Thread() {
            public void run() {
                EditItemType form = (EditItemType) Gui.getDialog(Dialog.EditItemType);
                form.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Updating Item Type Information...");

                String oldtype = form.getItemTypeOld();
                String newtype = form.getItemTypeNew();
                Database.item.updateItemType(oldtype, newtype);

                Gui.refreshComboBoxes(Database.item.readItemTypes(), Database.person.readTeams());

                form.setEnabled(true);
                form.dispose();

                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                busy = false;

                Actions.item.gotoBrowseItem();
            }
        };
        t.start();
    }

    public void doRefreshItemType() {
        Thread t = new Thread() {
            public void run() {
                Gui.setEnabled(false);
                while(busy) {

                }
                busy = true;

                Gui.setBusyEffect(true);
                Gui.setStatusBarMessage("Refreshing Item Types...");

                Gui.refreshComboBoxes(Database.item.readItemTypes(), Database.person.readTeams());

                Gui.setBusyEffect(false);
                Gui.setStatusBarMessage("Ready...");

                Gui.setEnabled(true);

                busy = false;
            }
        };
        t.start();
    }

}
